package com.mvvm.store.ui.into;

import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.device.ScanManager;
import android.device.scanner.configuration.PropertyID;
import android.device.scanner.configuration.Triggering;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.leo.utilspro.utils.ToastUtils;
import com.mvvm.store.R;
import com.mvvm.store.base.BaseActivity;
import com.mvvm.store.base.NormalViewModel;
import com.mvvm.store.bean.basebean.IntoMaterialBean;
import com.mvvm.store.databinding.ActivityScanBinding;
import com.mvvm.store.roombatabase.IntoMaterDatabase;
import com.mvvm.store.roombatabase.IntoMaterialDao;
import com.mvvm.store.ui.stockup.StockUpSweptFragment;

import java.util.List;

public class ScanIntoActivity extends BaseActivity<NormalViewModel, ActivityScanBinding> {
    //--------------------------------------------------------------------------------------------------------------------------------
    private static final String ACTION_DECODE = ScanManager.ACTION_DECODE;   // default action
    private static final String ACTION_DECODE_IMAGE_REQUEST = "action.scanner_capture_image";
    private static final String ACTION_CAPTURE_IMAGE = "scanner_capture_image_result";
    private static final String BARCODE_STRING_TAG = ScanManager.BARCODE_STRING_TAG;
    private static final String BARCODE_TYPE_TAG = ScanManager.BARCODE_TYPE_TAG;
    private static final String BARCODE_LENGTH_TAG = ScanManager.BARCODE_LENGTH_TAG;
    private static final String DECODE_DATA_TAG = ScanManager.DECODE_DATA_TAG;
    private static final String DECODE_CAPTURE_IMAGE_KEY = "bitmapBytes";
    private ScanManager mScanManager = null;
    private static boolean mScanEnable = true;
    private static boolean mScanCaptureImageShow = false;
    private static final int MSG_SHOW_SCAN_RESULT = 1;
    private static final int MSG_SHOW_SCAN_IMAGE = 2;
    private static final int[] SCAN_KEYCODE = {520, 521, 522, 523};
    private IntoMaterialDao intoMaterialDa;
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            System.out.println("onReceive , action:" + action);
            // Get Scan Image . Make sure to make a request before getting a scanned image
            if (ACTION_CAPTURE_IMAGE.equals(action)) {
                byte[] imagedata = intent.getByteArrayExtra(DECODE_CAPTURE_IMAGE_KEY);
                if (imagedata != null && imagedata.length > 0) {
                    Bitmap bitmap = BitmapFactory.decodeByteArray(imagedata, 0, imagedata.length);
                    Message msg = mHandler.obtainMessage(MSG_SHOW_SCAN_IMAGE);
                    msg.obj = bitmap;
                    mHandler.sendMessage(msg);
                } else {
                    System.out.println("onReceive , ignore imagedata:" + imagedata);
                }
            } else {
                // Get scan results, including string and byte data etc.
                byte[] barcode = intent.getByteArrayExtra(DECODE_DATA_TAG);
                int barcodeLen = intent.getIntExtra(BARCODE_LENGTH_TAG, 0);
                byte temp = intent.getByteExtra(BARCODE_TYPE_TAG, (byte) 0);
                String barcodeStr = intent.getStringExtra(BARCODE_STRING_TAG);
                if (mScanCaptureImageShow) {
                    // Request images of this scan
                    context.sendBroadcast(new Intent(ACTION_DECODE_IMAGE_REQUEST));
                }
                System.out.println("barcode type:" + temp);
                String scanResult = new String(barcode, 0, barcodeLen);
                // print scan results.
                scanResult = " length：" + barcodeLen + "\nbarcode：" + scanResult + "\nbytesToHexString：" + bytesToHexString(barcode) + "\nbarcodeStr:" + barcodeStr;
                Message msg = mHandler.obtainMessage(MSG_SHOW_SCAN_RESULT);
                msg.obj = barcodeStr;
                mHandler.sendMessage(msg);
            }
        }
    };

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MSG_SHOW_SCAN_RESULT:
                    String scanResult = (String) msg.obj;
                    System.out.println("scanResult"+scanResult);
                    printScanResult(scanResult);
                    break;
            }
        }
    };
    /**
     * @param register , ture register , false unregister
     */
    private void registerReceiver(boolean register) {
        if (register && mScanManager != null) {
            IntentFilter filter = new IntentFilter();
            int[] idbuf = new int[]{PropertyID.WEDGE_INTENT_ACTION_NAME, PropertyID.WEDGE_INTENT_DATA_STRING_TAG};
            String[] value_buf = mScanManager.getParameterString(idbuf);
            if (value_buf != null && value_buf[0] != null && !value_buf[0].equals("")) {
                filter.addAction(value_buf[0]);
            } else {
                filter.addAction(ACTION_DECODE);
            }
            filter.addAction(ACTION_CAPTURE_IMAGE);

            this.registerReceiver(mReceiver, filter);
        } else if (mScanManager != null) {
            mScanManager.stopDecode();
            this.unregisterReceiver(mReceiver);
        }
    }

    /**
     * byte[] toHex String
     *
     * @param src
     * @return String
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * Intent Output Mode print scan results.
     *
     * @param msg
     */
    private void printScanResult(String msg) {
        if (msg == null) {
            System.out.println("printScanResult , ignore to show msg:" + msg + ",showScanResult");
            return;
        }
       //
        binding.etScanCode.setText(msg);
        System.out.println("msg"+msg);

    }
    private void initScan() {
        mScanManager = new ScanManager();
        mScanManager.switchOutputMode(0);
        boolean powerOn = mScanManager.getScannerState();
        if (!powerOn) {
            powerOn = mScanManager.openScanner();
            if (!powerOn) {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage("Scanner cannot be turned on!");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                AlertDialog mAlertDialog = builder.create();
                mAlertDialog.show();
            }
        }
    }

    /**
     * ScanManager.getTriggerMode
     *
     * @return
     */
    private Triggering getTriggerMode() {
        Triggering mode = mScanManager.getTriggerMode();
        return mode;
    }

    /**
     * ScanManager.getTriggerLockState
     *
     * @return
     */
    private boolean getlockTriggerState() {
        boolean state = mScanManager.getTriggerLockState();
        return state;
    }

    /**
     * ScanManager.startDecode
     */
    private void startDecode() {
        if (!mScanEnable) {
            System.out.println("startDecode ignore, Scan enable:" + mScanEnable);
            return;
        }
        boolean lockState = getlockTriggerState();
        if (lockState) {
            System.out.println("startDecode ignore, Scan lockTrigger state:" + lockState);
            return;
        }
        if (mScanManager != null) {
            mScanManager.startDecode();
        }
    }

    /**
     * ScanManager.stopDecode
     */
    private void stopDecode() {
        if (!mScanEnable) {
            System.out.println("stopDecode ignore, Scan enable:" + mScanEnable);
            return;
        }
        if (mScanManager != null) {
            mScanManager.stopDecode();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        System.out.println("onPauseonPauseonPause");
        registerReceiver(false);
    }

    @Override
    public void onResume() {
        super.onResume();
        initScan();
        registerReceiver(true);
    }

    @Override
    protected int getContentViewId() {
        return R.layout.activity_scan;
    }

    @Override
    protected void processLogic() {
        intoMaterialDa= IntoMaterDatabase.getInstance(this).materialDao();
        binding.leoTitleBar.bar_left_btn.setBackgroundResource(R.mipmap.return_images);
    }

    @Override
    protected void setListener() {
        binding.setOnClickListener(this::onClick);
        binding.leoTitleBar.bar_left_btn.setOnClickListener(this::onClick);
        ButtonListener listener = new ButtonListener();
        binding.llScanClick.setOnTouchListener(listener);
        binding.llScanClick.setOnClickListener(listener);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){

            case R.id.bt_scan_result:
                if(TextUtils.isEmpty(binding.etScanCode.getText().toString().trim())){
                    Toast.makeText(this, "未扫码获取到数据", Toast.LENGTH_SHORT).show();
                }else {
                    List<IntoMaterialBean> intoMaterialBeansss= intoMaterialDa.getMaterialInfoScanInforResult(binding.etScanCode.getText().toString().trim());
                    for (int i=0;i<intoMaterialBeansss.size();i++){
                        intoMaterialDa.delete(intoMaterialBeansss.get(i));
                    }
                    //跳转到列表界面
                    SharedPreferences sharedPreferences = getSharedPreferences("codeInfo", MODE_PRIVATE);
                    SharedPreferences.Editor editor = sharedPreferences.edit();
                    editor.putString("codeResult", binding.etScanCode.getText().toString().trim());
                    //保存key-value对到文件中
                    editor.commit();
                    Intent intent=new Intent(ScanIntoActivity.this,IntoStorageActivity.class);
                    intent.putExtra("codeResult", binding.etScanCode.getText().toString().trim());
                    startActivityForResult(intent, 100);
                }
                break;

            case R.id.bar_left_btn:
                this.finish();
                break;
            default:
                break;
        }
    }

    /**
     * Button helper
     */
    class ButtonListener implements View.OnClickListener, View.OnTouchListener {
        public void onClick(View v) {
            System.out.println("ButtonListener onClick");
        }

        public boolean onTouch(View v, MotionEvent event) {
            if (v.getId() == R.id.ll_scan_click) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    if (getTriggerMode() == Triggering.HOST) {
                        stopDecode();
                    }
                }
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    startDecode();
                }
            }
            return false;
        }

    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}
